from pml import Objects
from pml import PML

class PMStringObject(Objects.object.typeobject):
    def __init__(self, value: str = ''):
        super().__init__('string')
        self.value = value
        self.len = PML.object.ChangeObject.PMLInteger_FromInt(value.__len__())
    def __repr__(self):
        return self.value
    def __str__(self):
        return self.value

    def __eq__(self, other):
        if isinstance(other, str):
            return self.value == other
        elif isinstance(other, type):
            return other == PMStringObject
        else:
            return self.value == other.obj.value
    def __hash__(self):
        return self.value.__hash__()
    def __len__(self):
        return self.value.__len__()

    def __reduce__(self):
        return PMStringObject, (self.value, )

    def getObject(self):
        self.methods['__init__'] = self.tp_init
        self.methods['__print__'] = self.tp_print

        self.methods['__string__'] = self.tp_string
        self.methods['__boolean__'] = self.tp_boolean

        self.methods['__addition__'] = self.tp_addition

        self.methods['__eq__'] = self.tp_eq

        self.methods['length'] = self.len

        return self

    @staticmethod
    def tp_init(frame, this, position, value):
        pass

    @staticmethod
    def tp_print(frame, this, position):
        return this.tp_string(frame, this, position=position)

    @staticmethod
    def tp_boolean(frame, this, position):
        return Objects.object.PMTypeObject(Objects.PMBooleanObject.PMBooleanObject(len(this.value).__bool__()).getObject())

    @staticmethod
    def tp_string(frame, this, position):
        return Objects.object.PMTypeObject(this)

    @staticmethod
    def tp_addition(frame, this: 'PMStringObject', position, other):
        other = PML.tool.CallFunction.CallFunctionAndCheckReturnType(frame, other, other.getMember('__string__'), None, type=PMStringObject)
        return Objects.object.PMTypeObject(PMStringObject(this.value + other.obj.value).getObject())

    @staticmethod
    def tp_eq(frame, this: 'PMStringObject', position, other):
        return Objects.object.PMTypeObject(Objects.PMBooleanObject.PMBooleanObject(this.__eq__(other)).getObject())
